/*
 *  $Id: Frame.cs 1232 2010-12-07 13:16:37Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System.Collections.Generic;

using AgateLib.Geometry;

using Nereal.Serialization;

using Ragima.Helper;

namespace Ragima.UI {
    /// <summary>
    /// Фрейм: групповой виджет, содержащий в себе другие виджеты.
    /// </summary>
    [TypeId("frame")]
    public class Frame : Widget {
        private List<Widget> _childs;

        public Frame() {
            _childs = new List<Widget>();
        }

        /// <summary>
        /// Число вложенных виджетов.
        /// </summary>
        public int ChildCount {
            get { return _childs.Count; }
        }

        /// <summary>
        /// Вложенные виджеты.
        /// </summary>
        public Widget this[int index] {
            get { return _childs[index]; }
        }

        /// <summary>
        /// Вложенные виджеты.
        /// </summary>
        public IEnumerable<Widget> Childs {
            get { return _childs; }
        }

        /// <summary>
        /// Список вложенных виджетов (только для сериализатора).
        /// </summary>
        [Serialize, XmlName("childs", null)]
        private List<Widget> ChildWidgets {
            get { return _childs; }
            set {
                ClearChilds();
                foreach (var child in value)
                    child.Parent = this;
            }
        }

        /// <summary>
        /// Добавляет вложенный виджет.
        /// </summary>
        protected override void AddChild(Widget widget) {
            _childs.Add(widget);
        }

        /// <summary>
        /// Удаляет вложенный виджет.
        /// </summary>
        protected override void RemoveChild(Widget widget) {
            _childs.Remove(widget);
        }

        /// <summary>
        /// Удаляет все вложенные виджеты.
        /// </summary>
        protected void ClearChilds() {
            while (_childs.Count > 0)
                _childs[_childs.Count - 1].Parent = null;
        }

        /// <summary>
        /// Идет виджет по идентификатору.
        /// </summary>
        public override Widget FindWidget(string id) {
            var widget = base.FindWidget(id);
            int i = 0;
            while (widget == null && i < _childs.Count) {
                widget = _childs[i].FindWidget(id);
                i++;
            }
            return widget;
        }

        /// <summary>
        /// Рисует фрейм.
        /// </summary>
        public override void Draw() {
            DrawBackground();
            DrawChilds();
        }

        /// <summary>
        /// Рисует все вложенные виджеты,
        /// </summary>
        protected virtual void DrawChilds() {
            foreach (var child in Childs)
                if (child.Visible)
                    child.Draw();
        }

        /// <summary>
        /// Обрабатывает фрейм.
        /// </summary>
        public override void Process() {
            ProcessChilds();
        }

        /// <summary>
        /// Обрабатывает все вложенные виджеты.
        /// </summary>
        protected virtual void ProcessChilds() {
            foreach (var child in Childs)
                child.Process();
        }

        /// <summary>
        /// Ищет вложенный виджет по точке.
        /// </summary>
        public override Widget FindChild(Point point) {
            var widget = base.FindChild(point);
            if (widget != null) {
                var p = point.Sub(Location);
                for (int i = _childs.Count - 1; i >= 0; i--) {
                    var child = _childs[i].FindChild(p);
                    if (child != null)
                        return child;
                }
            }
            return widget;
        }
    }
}
